﻿using Logistics.Web.Infrastructure;
using Logistics.Web.Models.Order;
using Nop.Core;
using Nop.Core.Infrastructure;
using Nop.Services.Logging;
using Nop.Web.Framework.Security;
using Nop.Web.Framework.UI;
using System;
using System.Collections.Generic;
using System.Web.Mvc;

namespace Logistics.Web.Controllers
{
    [NopHttpsRequirement(SslRequirement.NoMatter)]
    [LogisticsClosed]
    public class BaseController : Controller
    {
        /// <summary>
        /// Log exception
        /// </summary>
        /// <param name="exc">Exception</param>
        protected void LogException(Exception exc)
        {
            var logger = EngineContext.Current.Resolve<ILogger>();
            logger.Error(exc.Message, exc, GetCurrentCustomer());
        }

        /// <summary>
        /// Log Error
        /// </summary>
        /// <param name="msg">Error Message</param>
        protected void LogError(string msg)
        {
            var logger = EngineContext.Current.Resolve<ILogger>();
            logger.Error(msg, null, GetCurrentCustomer());
        }

        /// <summary>
        /// Get current customer
        /// </summary>
        /// <returns></returns>
        private Nop.Core.Domain.Customers.Customer GetCurrentCustomer()
        {
            var workContext = EngineContext.Current.Resolve<IWorkContext>();
            if (workContext != null)
            {
                return workContext.CurrentCustomer;
            }
            return null;
        }
        /// <summary>
        /// Display success notification
        /// </summary>
        /// <param name="message">Message</param>
        /// <param name="persistForTheNextRequest">A value indicating whether a message should be persisted for the next request</param>
        protected virtual void SuccessNotification(string message, bool persistForTheNextRequest = true)
        {
            AddNotification(NotifyType.Success, message, persistForTheNextRequest);
        }
        /// <summary>
        /// Display error notification
        /// </summary>
        /// <param name="message">Message</param>
        /// <param name="persistForTheNextRequest">A value indicating whether a message should be persisted for the next request</param>
        protected virtual void ErrorNotification(string message, bool persistForTheNextRequest = true)
        {
            AddNotification(NotifyType.Error, message, persistForTheNextRequest);
        }
        /// <summary>
        /// Display error notification
        /// </summary>
        /// <param name="exception">Exception</param>
        /// <param name="persistForTheNextRequest">A value indicating whether a message should be persisted for the next request</param>
        /// <param name="logException">A value indicating whether exception should be logged</param>
        protected virtual void ErrorNotification(Exception exception, bool persistForTheNextRequest = true, bool logException = true)
        {
            if (logException)
                LogException(exception);
            AddNotification(NotifyType.Error, exception.Message, persistForTheNextRequest);
        }
        /// <summary>
        /// Display notification
        /// </summary>
        /// <param name="type">Notification type</param>
        /// <param name="message">Message</param>
        /// <param name="persistForTheNextRequest">A value indicating whether a message should be persisted for the next request</param>
        protected virtual void AddNotification(NotifyType type, string message, bool persistForTheNextRequest)
        {
            string dataKey = string.Format("nop.notifications.{0}", type);
            if (persistForTheNextRequest)
            {
                if (TempData[dataKey] == null)
                    TempData[dataKey] = new List<string>();
                ((List<string>)TempData[dataKey]).Add(message);
            }
            else
            {
                if (ViewData[dataKey] == null)
                    ViewData[dataKey] = new List<string>();
                ((List<string>)ViewData[dataKey]).Add(message);
            }
        }

        /// <summary>
        /// Used to set the system keyword when logging user activities
        /// </summary>
        protected string SystemKeyword = null;

        /// <summary>
        /// Logging user activities
        /// </summary>
        /// <param name="systemKeyword"></param>
        /// <param name="comment"></param>
        /// <param name="customer"></param>
        /// <param name="service"></param>
        /// <param name="commentParams"></param>
        protected virtual void LogCustomerActivity(
            string comment, 
            Nop.Core.Domain.Customers.Customer customer, 
            ICustomerActivityService service, 
            params object[] commentParams)
        {
            if (customer == null)
            {
                var workContext = EngineContext.Current.Resolve<IWorkContext>();
                if (workContext != null)
                {
                    customer = workContext.CurrentCustomer;
                }
            }
            if (service == null)
            {
                service = EngineContext.Current.Resolve<ICustomerActivityService>();
            }

            if (service != null && customer != null)
            {
                service.InsertActivity(SystemKeyword ?? "Logistics", comment, customer, commentParams);
            }
        }

        /// <summary>
        /// Handle access denied result.
        /// </summary>
        /// <returns></returns>
        protected virtual ActionResult AccessDeniedView()
        {
            return RedirectToRoute("HomePage");
        }
        /// <summary>
        /// Handle fatal errors
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="customer"></param>
        /// <param name="exc"></param>
        /// <returns></returns>
        protected virtual ActionResult FatalErrorView(string msg, Nop.Core.Domain.Customers.Customer customer = null, Exception exc = null)
        {
            var logger = EngineContext.Current.Resolve<ILogger>();

            logger.Error(msg, exc, customer ?? GetCurrentCustomer());

            return RedirectToRoute("HomePage");
        }
        /// <summary> 
        /// Handle fatal errors for ajax
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="customer"></param>
        /// <param name="exc"></param>
        /// <returns></returns>
        protected virtual JsonResult FatalErrorJsonView(string msg, Nop.Core.Domain.Customers.Customer customer = null, Exception exc = null, bool removeOrder = true)
        {
            var logger = EngineContext.Current.Resolve<ILogger>();

            logger.Error(msg, exc, customer ?? GetCurrentCustomer());

            var restartOrder = "";
            if (removeOrder)
                restartOrder = "<input type='button' data-action='clearOrder' data-url='" + Url.Action("RemovePendingOrder", "Order") + "' value='Restart'/>";
            return Json(new { name = CommonValues.FatalErrorName, html = restartOrder });
        }
    }
}
